import 'dart:math';

import 'package:flutter/widgets.dart';

enum ScreenLayout {
  phone,
  tablet;

  bool get isPhoneLayout => this == ScreenLayout.phone;

  bool get isTabletLayout => this == ScreenLayout.tablet;
}

class ScreenUtil {
  factory ScreenUtil() {
    return _instance;
  }

  ScreenUtil._internal();

  static late ScreenUtil _instance;

  late Size _screenSize;
  late Size _baseDesignSize;
  late Size _tabletDesignSize;
  late ScreenLayout _screenLayout;
  late double _statusBarHeight;
  late double _bottomBarHeight;

  static void init({
    required Size screenSize,
    required BuildContext context,
  }) {
    const baseDesignSize = Size(375, 667);
    const tabletDesignSize = Size(744, 1133);

    _instance = ScreenUtil._internal();

    _instance._baseDesignSize = baseDesignSize;
    _instance._tabletDesignSize = tabletDesignSize;

    final portraitScreenSize = Size(
      min(screenSize.width, screenSize.height),
      max(screenSize.width, screenSize.height),
    );

    late ScreenLayout screenLayout;
    if (portraitScreenSize.width > 525) {
      screenLayout = ScreenLayout.tablet;
    } else {
      screenLayout = ScreenLayout.phone;
    }

    _instance._screenSize = portraitScreenSize;
    _instance._screenLayout = screenLayout;

    final window = View.of(context);

    _instance._statusBarHeight = window.padding.top / window.devicePixelRatio;
    _instance._bottomBarHeight = window.padding.bottom / window.devicePixelRatio;
  }

  ScreenLayout get screenLayout => _screenLayout;

  double get statusBarHeight => _statusBarHeight;

  double get bottomBarHeight => _bottomBarHeight;

  double get widthScaleFactor {
    return _screenSize.width / _baseDesignSize.width;
  }

  double get heightScaleFactor {
    return _screenSize.height / _baseDesignSize.height;
  }

  double get logWidthScaleFactor {
    return log(widthScaleFactor + e + 1) / log(e + 2);
  }

  double get layoutWidthScaleFactor {
    return switch (_screenLayout) {
      ScreenLayout.phone => _screenSize.width / _baseDesignSize.width,
      ScreenLayout.tablet => _screenSize.width / _tabletDesignSize.width,
    };
  }

  double get defaultScaleFactor {
    return 1.0;
  }
}
